package com.itheima.service.mongo.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.itheima.domain.mongo.*;
import com.itheima.service.mongo.MovementService;
import com.itheima.util.ConstantUtil;
import com.itheima.vo.PageBeanVo;
import org.apache.dubbo.config.annotation.Service;
import org.bson.types.ObjectId;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Sort;
import org.springframework.data.mongodb.core.MongoTemplate;
import org.springframework.data.mongodb.core.query.Criteria;
import org.springframework.data.mongodb.core.query.Query;
import org.springframework.data.mongodb.core.query.Update;


import java.util.ArrayList;
import java.util.List;

@Service
public class MovementServiceImpl implements MovementService {
    @Autowired
    private MongoTemplate mongoTemplate;

    @Autowired
    private IdService idService;

    //保存动态
    @Override
    public void save(Movement movement) {
        //1. 向动态详情表插入动态数据,得到id
        movement.setPid(idService.getNextId(ConstantUtil.MOVEMENT_ID));//获取大数据使用的动态id
        mongoTemplate.save(movement);

        ObjectId movementId = movement.getId();//动态id

        //2. 将动态id保存到我的动态表
        MyMovement myMovement = new MyMovement();
        myMovement.setPublishId(movementId);
        myMovement.setCreated(System.currentTimeMillis());
        mongoTemplate.save(myMovement, ConstantUtil.MOVEMENT_MINE + movement.getUserId());

        //3. 查询好友关系表,得到所有的好友
        Query query = new Query(
                Criteria.where("userId").is(movement.getUserId())
        );
        List<Friend> friendList = mongoTemplate.find(query, Friend.class);

        //4. 遍历所有好友,向他们的好友关系表中插入动态id
        if (CollectionUtil.isNotEmpty(friendList)) {
            for (Friend friend : friendList) {
                Long friendId = friend.getFriendId();//好友的id

                FriendMovement friendMovement = new FriendMovement();
                friendMovement.setUserId(movement.getUserId());//动态发布者的id
                friendMovement.setPublishId(movementId);//动态id
                friendMovement.setCreated(System.currentTimeMillis());//时间
                //保存
                mongoTemplate.save(friendMovement, ConstantUtil.MOVEMENT_FRIEND + friendId);
            }
        }
    }

    //1. 从我的动态表中分页查询动态id集合
    @Override
    public PageBeanVo findMyMovement(Long userId, Integer pageNum, Integer pageSize) {
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))//时间倒序
                .skip((pageNum - 1) * pageSize).limit(pageSize);
        List<MyMovement> myMovementList = mongoTemplate.find(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);


        //2. 遍历动态id的集合,得到动态id
        List<Movement> movementList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(myMovementList)) {
            for (MyMovement myMovement : myMovementList) {
                //3. 根据动态id查询动态详情
                ObjectId movementId = myMovement.getPublishId();//动态id
                Movement movement = mongoTemplate.findById(movementId, Movement.class);//根据动态id获取动态详情对象
                if (movement.getState() == 1) {
                    movementList.add(movement);
               }
            }
        }

        //4. 查询总记录数
        long count = mongoTemplate.count(query, MyMovement.class, ConstantUtil.MOVEMENT_MINE + userId);
        //组装返回结果
        return  new PageBeanVo(pageNum, pageSize, count, movementList);
    }

   //查询好友列表动态
    @Override
    public PageBeanVo findFriendMovement(Long userId, Integer pageNum, Integer pageSize) {
        //1. 从我的好友表中分页查询到动态的id集合
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))//时间倒序
                .skip((pageNum - 1) * pageSize).limit(pageSize);
        List<FriendMovement> friendMovementList
                = mongoTemplate.find(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);//好友动态列表

        //2. 遍历id集合,获取动态详情
        List<Movement> movementList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(friendMovementList)){
            for (FriendMovement friendMovement : friendMovementList) {
                ObjectId movementId = friendMovement.getPublishId();//动态id
                Movement movement = mongoTemplate.findById(movementId, Movement.class);//根据动态id获取动态详情对象
                if (movement.getState() == 1) {
                    movementList.add(movement);
                }
            }
        }
        //3. 查询总记录数
        long count = mongoTemplate.count(query, FriendMovement.class, ConstantUtil.MOVEMENT_FRIEND + userId);

        //4. 组装返回结果
        return new PageBeanVo(pageNum,pageSize,count,movementList);
    }

    //分页查询推荐给我的动态
    @Override
    public PageBeanVo findRecommendMovement(Long userId, Integer pageNum, Integer pageSize) {
        //1. 从推荐动态表根据登录用户id分页查询推荐动态集合
        Query query = new Query(
                Criteria.where("userId").is(userId)
        ).with(Sort.by(Sort.Order.desc("score"), Sort.Order.desc("created")))//按照推荐分数 发布时间倒序排
                .skip((pageNum - 1) * pageSize).limit(pageSize);

        List<RecommendMovement> recommendMovementList = mongoTemplate.find(query, RecommendMovement.class);

        //2. 遍历集合获取到动态id
        List<Movement> movementList = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(recommendMovementList)){
            for (RecommendMovement recommendMovement : recommendMovementList) {
                //3. 根据动态id查询动态详情
                ObjectId movementId = recommendMovement.getPublishId();//动态id
                Movement movement = mongoTemplate.findById(movementId, Movement.class);//根据动态id获取动态详情对象
                if (movement.getState() == 1) {
                    movementList.add(movement);
                }
            }
        }

        //4. 统计数量
        long count = mongoTemplate.count(query, RecommendMovement.class);
        //5 组装返回结果
        return   new PageBeanVo(pageNum, pageSize, count, movementList);
    }

    //根据动态id查询动态信息
    @Override
    public Movement findMyMovementById(String movementId) {
        return mongoTemplate.findById(movementId,Movement.class);
    }

    @Override
    public PageBeanVo findMovementList(Long uid, Integer stateInt, Integer pageNum, Integer pageSize) {
        //1. 构建查询条件
        //1-1 基础架子
        Query query = new Query()
                .with(Sort.by(Sort.Order.desc("created")))
                .skip((pageNum - 1) * pageSize).limit(pageSize);

        //1-2 拼接条件
        if (uid != null) {
            query.addCriteria(Criteria.where("userId").is(uid));
        }
        if (stateInt != null) {
            query.addCriteria(Criteria.where("state").is(stateInt));
        }

        //2. 执行查询
        List<Movement> movementList = mongoTemplate.find(query, Movement.class);

        //3. 统计总记录数
        long count = mongoTemplate.count(query, Movement.class);

        //4. 返回结果
        return new PageBeanVo(pageNum,pageSize,count,movementList);
    }

    //动态审核
    @Override
    public void updateMovementState(String movementId, Integer state) {
        //定义查询
        Query query = new Query(Criteria.where("id").is(new ObjectId(movementId)));

        //定义更新
        Update update = new Update();
        update.set("state", state);

        //执行
        mongoTemplate.updateFirst(query, update, Movement.class);
    }

    //动态评审通过
    @Override
    public void MovementPass(List<String> movementIds) {
        for (String movementId : movementIds) {
            Query query = new Query(Criteria.where("id").is(new ObjectId(movementId)));
            Update update = new Update();
            update.set("state", 1);
            mongoTemplate.updateFirst(query, update, Movement.class);
        }

    }
    //动态评审未通过
    @Override
    public void MovementReject(List<String> movementIds) {
        for (String movementId : movementIds) {
            Query query = new Query(Criteria.where("id").is(new ObjectId(movementId)));
            Update update = new Update();
            update.set("state", 2);
            mongoTemplate.updateFirst(query, update, Movement.class);
        }
    }
}